home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_300 / 334_03 / util.c < prev    next >
Text File  |  1991-02-04  |  12KB  |  551 lines

  1. /* GNUPLOT - util.c */
  2. /*
  3.  * Copyright (C) 1986, 1987, 1990   Thomas Williams, Colin Kelley
  4.  *
  5.  * Permission to use, copy, and distribute this software and its
  6.  * documentation for any purpose with or without fee is hereby granted, 
  7.  * provided that the above copyright notice appear in all copies and 
  8.  * that both that copyright notice and this permission notice appear 
  9.  * in supporting documentation.
  10.  *
  11.  * Permission to modify the software is granted, but not the right to
  12.  * distribute the modified code.  Modifications are to be distributed 
  13.  * as patches to released version.
  14.  *  
  15.  * This software  is provided "as is" without express or implied warranty.
  16.  * 
  17.  *
  18.  * AUTHORS
  19.  * 
  20.  *   Original Software:
  21.  *     Thomas Williams,  Colin Kelley.
  22.  * 
  23.  *   Gnuplot 2.0 additions:
  24.  *       Russell Lang, Dave Kotz, John Campbell.
  25.  * 
  26.  * send your comments or suggestions to (pixar!info-gnuplot@sun.com).
  27.  * 
  28.  */
  29.  
  30. #include <ctype.h>
  31. #include <setjmp.h>
  32. #include <stdio.h>
  33. #include <errno.h>
  34. #include "plot.h"
  35.  
  36. BOOLEAN screen_ok;
  37.     /* TRUE if command just typed; becomes FALSE whenever we
  38.         send some other output to screen.  If FALSE, the command line
  39.         will be echoed to the screen before the ^ error message. */
  40.  
  41. #ifndef vms
  42. #ifndef __ZTC__
  43. extern int errno;
  44. extern int sys_nerr;
  45. extern char *sys_errlist[];
  46. #endif
  47. #endif /* vms */
  48.  
  49. extern char input_line[];
  50. extern struct lexical_unit token[];
  51. extern jmp_buf env;    /* from plot.c */
  52. extern int inline_num;        /* from command.c */
  53. extern BOOLEAN interactive;    /* from plot.c */
  54. extern char *infile_name;    /* from plot.c */
  55.  
  56. /*
  57.  * equals() compares string value of token number t_num with str[], and
  58.  *   returns TRUE if they are identical.
  59.  */
  60. equals(t_num, str)
  61. int t_num;
  62. char *str;
  63. {
  64. register int i;
  65.  
  66.     if (!token[t_num].is_token)
  67.         return(FALSE);                /* must be a value--can't be equal */
  68.     for (i = 0; i < token[t_num].length; i++) {
  69.         if (input_line[token[t_num].start_index+i] != str[i])
  70.             return(FALSE);
  71.         }
  72.     /* now return TRUE if at end of str[], FALSE if not */
  73.     return(str[i] == '\0');
  74. }
  75.  
  76.  
  77.  
  78. /*
  79.  * almost_equals() compares string value of token number t_num with str[], and
  80.  *   returns TRUE if they are identical up to the first $ in str[].
  81.  */
  82. almost_equals(t_num, str)
  83. int t_num;
  84. char *str;
  85. {
  86. register int i;
  87. register int after = 0;
  88. register start = token[t_num].start_index;
  89. register length = token[t_num].length;
  90.  
  91.     if (!token[t_num].is_token)
  92.         return(FALSE);                /* must be a value--can't be equal */
  93.     for (i = 0; i < length + after; i++) {
  94.         if (str[i] != input_line[start + i]) {
  95.             if (str[i] != '$')
  96.                 return(FALSE);
  97.             else {
  98.                 after = 1;
  99.                 start--;    /* back up token ptr */
  100.                 }
  101.             }
  102.         }
  103.  
  104.     /* i now beyond end of token string */
  105.  
  106.     return(after || str[i] == '$' || str[i] == '\0');
  107. }
  108.  
  109.  
  110.  
  111. isstring(t_num)
  112. int t_num;
  113. {
  114.     
  115.     return(token[t_num].is_token &&
  116.            (input_line[token[t_num].start_index] == '\'' ||
  117.            input_line[token[t_num].start_index] == '\"'));
  118. }
  119.  
  120.  
  121. isnumber(t_num)
  122. int t_num;
  123. {
  124.     return(!token[t_num].is_token);
  125. }
  126.  
  127.  
  128. isletter(t_num)
  129. int t_num;
  130. {
  131.     return(token[t_num].is_token &&
  132.             (isalpha(input_line[token[t_num].start_index])));
  133. }
  134.  
  135.  
  136. /*
  137.  * is_definition() returns TRUE if the next tokens are of the form
  138.  *   identifier =
  139.  *        -or-
  140.  *   identifier ( identifer ) =
  141.  */
  142. is_definition(t_num)
  143. int t_num;
  144. {
  145.     return (isletter(t_num) &&
  146.             (equals(t_num+1,"=") ||            /* variable */
  147.             (equals(t_num+1,"(") &&        /* function */
  148.              isletter(t_num+2)   &&
  149.              equals(t_num+3,")") &&
  150.              equals(t_num+4,"=") )
  151.         ));
  152. }
  153.  
  154.  
  155.  
  156. /*
  157.  * copy_str() copies the string in token number t_num into str, appending
  158.  *   a null.  No more than MAX_ID_LEN chars are copied.
  159.  */
  160. copy_str(str, t_num)
  161. char str[];
  162. int t_num;
  163. {
  164. register int i = 0;
  165. register int start = token[t_num].start_index;
  166. register int count;
  167.  
  168.     if ((count = token[t_num].length) > MAX_ID_LEN)
  169.         count = MAX_ID_LEN;
  170.     do {
  171.         str[i++] = input_line[start++];
  172.         } while (i != count);
  173.     str[i] = '\0';
  174. }
  175.  
  176.  
  177. /*
  178.  * quote_str() does the same thing as copy_str, except it ignores the
  179.  *   quotes at both ends.  This seems redundant, but is done for
  180.  *   efficency.
  181.  */
  182. quote_str(str, t_num)
  183. char str[];
  184. int t_num;
  185. {
  186. register int i = 0;
  187. register int start = token[t_num].start_index + 1;
  188. register int count;
  189.  
  190.     if ((count = token[t_num].length - 2) > MAX_ID_LEN)
  191.         count = MAX_ID_LEN;
  192.     if (count>0) {
  193.         do {
  194.             str[i++] = input_line[start++];
  195.             } while (i != count);
  196.     }
  197.     str[i] = '\0';
  198. }
  199.  
  200.  
  201. /*
  202.  * quotel_str() does the same thing as quote_str, except it uses
  203.  * MAX_LINE_LEN instead of MAX_ID_LEN. 
  204.  */ 
  205. quotel_str(str, t_num) 
  206. char str[]; 
  207. int t_num; 
  208. {
  209. register int i = 0;
  210. register int start = token[t_num].start_index + 1;
  211. register int count;
  212.  
  213.     if ((count = token[t_num].length - 2) > MAX_LINE_LEN)
  214.         count = MAX_LINE_LEN;
  215.     if (count>0) {
  216.         do {
  217.             str[i++] = input_line[start++];
  218.             } while (i != count);
  219.     }
  220.     str[i] = '\0';
  221. }
  222.  
  223.  
  224. /*
  225.  *    capture() copies into str[] the part of input_line[] which lies between
  226.  *    the begining of token[start] and end of token[end].
  227.  */
  228. capture(str,start,end)
  229. char str[];
  230. int start,end;
  231. {
  232. register int i,e;
  233.  
  234.     e = token[end].start_index + token[end].length;
  235.     for (i = token[start].start_index; i < e && input_line[i] != '\0'; i++)
  236.         *str++ = input_line[i];
  237.     *str = '\0';
  238. }
  239.  
  240.  
  241. /*
  242.  *    m_capture() is similar to capture(), but it mallocs storage for the
  243.  *  string.
  244.  */
  245. m_capture(str,start,end)
  246. char **str;
  247. int start,end;
  248. {
  249. register int i,e;
  250. register char *s;
  251.  
  252.     if (*str)        /* previous pointer to malloc'd memory there */
  253.         free(*str);
  254.     e = token[end].start_index + token[end].length;
  255.     *str = alloc((unsigned int)(e - token[start].start_index + 1), "string");
  256.      s = *str;
  257.      for (i = token[start].start_index; i < e && input_line[i] != '\0'; i++)
  258.       *s++ = input_line[i];
  259.      *s = '\0';
  260. }
  261.  
  262.  
  263. /*
  264.  *    m_quote_capture() is similar to m_capture(), but it removes
  265.     quotes from either end if the string.
  266.  */
  267. m_quote_capture(str,start,end)
  268. char **str;
  269. int start,end;
  270. {
  271. register int i,e;
  272. register char *s;
  273.  
  274.     if (*str)        /* previous pointer to malloc'd memory there */
  275.         free(*str);
  276.     e = token[end].start_index + token[end].length-1;
  277.     *str = alloc((unsigned int)(e - token[start].start_index + 1), "string");
  278.      s = *str;
  279.     for (i = token[start].start_index + 1; i < e && input_line[i] != '\0'; i++)
  280.      *s++ = input_line[i];
  281.     *s = '\0';
  282. }
  283.  
  284.  
  285. convert(val_ptr, t_num)
  286. struct value *val_ptr;
  287. int t_num;
  288. {
  289.     *val_ptr = token[t_num].l_val;
  290. }
  291.  
  292.  
  293.  
  294. disp_value(fp,val)
  295. FILE *fp;
  296. struct value *val;
  297. {
  298.         switch(val->type) {
  299.             case INT:
  300.                 fprintf(fp,"%d",val->v.int_val);
  301.                 break;
  302.             case CMPLX:
  303.                 if (val->v.cmplx_val.imag != 0.0 )
  304.                     fprintf(fp,"{%g, %g}",
  305.                         val->v.cmplx_val.real,val->v.cmplx_val.imag);
  306.                 else
  307.                     fprintf(fp,"%g", val->v.cmplx_val.real);
  308.                 break;
  309.             default:
  310.                 int_error("unknown type in disp_value()",NO_CARET);
  311.         }
  312. }
  313.  
  314.  
  315. double
  316. real(val)        /* returns the real part of val */
  317. struct value *val;
  318. {
  319.     switch(val->type) {
  320.         case INT:
  321.             return((double) val->v.int_val);
  322.         case CMPLX:
  323.             return(val->v.cmplx_val.real);
  324.     }
  325.     int_error("unknown type in real()",NO_CARET);
  326.     /* NOTREACHED */
  327.     return((double)0.0);
  328. }
  329.  
  330.  
  331. double
  332. imag(val)        /* returns the imag part of val */
  333. struct value *val;
  334. {
  335.     switch(val->type) {
  336.         case INT:
  337.             return(0.0);
  338.         case CMPLX:
  339.             return(val->v.cmplx_val.imag);
  340.     }
  341.     int_error("unknown type in real()",NO_CARET);
  342.     /* NOTREACHED */
  343.     return((double)0.0);
  344. }
  345.  
  346.  
  347.  
  348. double
  349. magnitude(val)        /* returns the magnitude of val */
  350. struct value *val;
  351. {
  352.     double sqrt();
  353.  
  354.     switch(val->type) {
  355.         case INT:
  356.             return((double) abs(val->v.int_val));
  357.         case CMPLX:
  358.             return(sqrt(val->v.cmplx_val.real*
  359.                     val->v.cmplx_val.real +
  360.                     val->v.cmplx_val.imag*
  361.                     val->v.cmplx_val.imag));
  362.     }
  363.     int_error("unknown type in magnitude()",NO_CARET);
  364.     /* NOTREACHED */
  365.     return((double)0.0);
  366. }
  367.  
  368.  
  369.  
  370. double
  371. angle(val)        /* returns the angle of val */
  372. struct value *val;
  373. {
  374.     doub